#ifndef HELPERS_H 
#define HELPERS_H

#include <string>
#include <sstream>
#include <iostream>
#include <fstream>
#include <time.h>
#include "Graph.h"
#include "Group.h"
#include "Chain.h"

using std::exception;
using std::string;
using std::cout;
using std::endl;

#undef _DEBUG

/*****************************************************************************/
// Logger
// interface for printing messages to the user
/*****************************************************************************/
class Logger
{
public:
	static void ChangeLogStream(bool isStdout);
	static void LogMessage(string msg, bool isToStdout = true);

private:
	static std::ostream s_OutStream;
};

/*****************************************************************************/
// GraphColoringException
// implements the Graph Coloring Exepetion interface
/*****************************************************************************/
class GraphColoringException : public exception
{
private:
	string m_ErrorDescription;
	
public:
	GraphColoringException(string description)
	{
		exception::exception();
		m_ErrorDescription = description;
		Logger::LogMessage("Exception :" + description);
	}

	string GetErrorDescription()
	{
		return m_ErrorDescription;
	}
};

/*****************************************************************************/
// Algorithms
// class for general algorithms checks 
/*****************************************************************************/
class Algorithms
{
public:
	
	//constants used by the coloring algorithms:
	// no limitation on the group size in the filling algorithms
	static const int _NO_SIZE_LIMITATION = -1;
	// name of a temp group, which is intended to replace another group
	static const int _TEMP_GROUP_NAME = -1;
	
	//interface functions:
	static void UpdateGraphAndGroupFromCopies(Graph& graph, Group& group, Group& copyGroup);
	// for validating the data structures when there is only one graph and one group.
	// should NOT be used to validate the data structures when working with chains
	static bool ValidateVertexDirectoryState(Graph* graph, Group* group, VertexDirectory* = NULL);
	// for validating the data structures when working with chains
	static bool ValidateVertexDirectoryState(Graph *graph, list<Group*> groups, set<int> groupNames, VertexDirectory* = NULL);
	static bool ValidateGroupIsIndependent(Group* group);
	static bool ValidateGroupInChainIsDisjoint(Chain* chain, Group* group);
	static bool ValidateGroupsAreDisjoint(Group* groupA, Group* groupB);
	static bool ValidateAllGroupsAreIndependent(Chain *chain);
};

/*****************************************************************************/
// Debug
// interface functions for helping in the development process
/*****************************************************************************/
class Debug
{
public:

#ifdef _DEBUG
	static const bool s_DebugOn = true; //turn off when development is finshed
#else
	static const bool s_DebugOn = false; //turn off when development is finshed
#endif

	static void PrintDebugMsg(string msg);
};

/*****************************************************************************/
// General functions
/*****************************************************************************/
string GetCurrentTime(bool isForFileName);

#endif //HELPERS_H